package de.koller.worlders.engine.environment;

import de.koller.oceanFramework.tree.Child;
import de.koller.worlders.WSea;
import de.koller.worlders.engine.tiles.data.MapData;
import de.koller.worlders.engine.tiles.light.LightContainer;
import de.koller.worlders.engine.tiles.light.LightSource;
import java.util.HashSet;
import java.util.Set;

public class EnvRoot extends WSea {
	
	public static final int TRANSLUCENT_GAP = 10;
	@Child public final DayCycle daycycle = new DayCycle();
	
	private int wishedDaylight = 0xffffffff;
	private int daylight = 0xffffffff;
	private final OutdoorType[][] outdoor = new OutdoorType[ MapData.MAP_SIZE ][ MapData.MAP_SIZE ];
	private final SunLightSources[] sunSources = new SunLightSources[ MapData.MAP_SIZE ];
	private final Set<Integer> changedX = new HashSet<>();
	
//	private ParticleTexture sunlight;
	
	@Override
	protected void init() {
		super.init();
		
//		ParticleTexture.MAG_FILTER = GL11.GL_NEAREST;
//		sunlight = ParticleTexture.generate( MapData.MAP_SIZE, MapData.MAP_SIZE );
		
		for( int x = 0; x < MapData.MAP_SIZE; x++ ) {
			sunSources[x] = new SunLightSources();
			updateColumn( x );
		}
		for( int x = 1; x < MapData.MAP_SIZE-1; x++ )
			updateLightColumn( x );
//		sunlight.flush();
	}
	
	private void updateColumn( int x ) {
		boolean v = true;
		for( int y = 1; y < MapData.MAP_SIZE; y++ ) {
			if( !v ) { outdoor[x][y] = OutdoorType.Indoor; continue; }
			v = wroot.getTileMap().searchTile( x, y ).getTile().getLightTranslucents() < TRANSLUCENT_GAP;
			if( v ) 
				outdoor[x][y] = OutdoorType.Outdoor;
			else
				outdoor[x][y] = OutdoorType.Indoor;
		}
		
//		for( int y = 0; y < MapData.MAP_SIZE; y++ )
//			if( outdoor[x][y] == OutdoorType.Indoor ) {
//				sunlight.setPixel( 0xff000000, x, y );
//			} else {
//				sunlight.setPixel( 0xffffffff, x, y );
//			}
	}

	private void updateLightColumn( int x ) {
		for( LightSource l : sunSources[x] )
			wroot.getTileMap().getLight().removeLightSource( l );
		sunSources[x].clear();
		
		boolean firstOccur = false;
		for( int y = MapData.MAP_SIZE-1; y > 1; y-- ) {
			if( outdoor[x][y] == OutdoorType.Indoor ) continue;
			if( !firstOccur && outdoor[x][y] == OutdoorType.Outdoor ) {
				firstOccur = true;
				LightSource s = wroot.getTileMap().getLight().addLightSource( x, y, daylight );
				sunSources[x].add( s );
			} else if( firstOccur )
				if( outdoor[x-1][y] == OutdoorType.Indoor || outdoor[x+1][y] == OutdoorType.Indoor ) {
					LightSource s = wroot.getTileMap().getLight().addLightSource( x, y, daylight );
					sunSources[x].add( s );
				}
		}
	}
	
	public void updateDayLight( int sx, int sy, int sw, int sh ) {
		int ax = sx - LightContainer.DIS; if( ax < 0 ) ax = 0;
		int ay = sy - LightContainer.DIS; if( ay < 0 ) ay = 0;
		int bx = sx+sw+LightContainer.DIS; if( bx > MapData.MAP_SIZE ) bx = MapData.MAP_SIZE;
		int by = sy+sh+LightContainer.DIS; if( by > MapData.MAP_SIZE ) by = MapData.MAP_SIZE;
		
		if( wishedDaylight != daylight ) {
			daylight = wishedDaylight;
			for( int x = ax; x < bx; x++ )
				for( LightSource ls : sunSources[x] )
					ls.setLight( daylight );
		}
		
		if( !changedX.isEmpty() ) {
			for( Integer x : changedX )
				updateColumn( x );
			for( Integer x : changedX ) {
				updateLightColumn( x+1 );
				updateLightColumn( x );
				updateLightColumn( x-1 );
			}
			changedX.clear();
//			sunlight.flush();
		}
	}
	
	public void setDayLight( int c ) {
		wishedDaylight = c;
	}
	
	public void tileChanged( int tx, int ty ) {
		if( tx == MapData.MAP_SIZE-1 || tx == 0 )
			return;
		changedX.add( tx );
	}

//	public ParticleTexture getSunlight() {
//		return sunlight;
//	}

	public int getDaylight() {
		return daylight;
	}

	public OutdoorType[][] getOutdoor() {
		return outdoor;
	}

	private class SunLightSources extends HashSet<LightSource> {}
	
}
